home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Text Processing / BBEdit Prefix⁄Suffix Lines / commentor.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  6KB  |  238 lines

  1. #include <SetupA4.h>
  2.  
  3. #include "ExternalInterface.h"
  4. #include "DialogUtilities.h"
  5.  
  6. /*    This extension is merely a modified version of the "Prefix/Suffix
  7.     Lines" that comes with BBEdit. I wanted an extension that would
  8.     allow me to comment out blocks of text in C code, this is the
  9.     result, as the default strings reveal.
  10.     The changes made are:
  11.         *    Separate strings for prefix and suffixes
  12.         *    Auto detection of insertion strings, rather than using
  13.             buttons
  14.     Known bugs:
  15.         *    Remove suffix does not check that the suffix truely exists
  16.         *    Processes the file in two passes, probably slowing things
  17.             down
  18.     Other possible bug:
  19.         *    I am not sure that I this will correctly update the
  20.             thermometer in the Progress window, and I have not tested it
  21.     Notes:
  22.     These humble modifications were made by Benjamin Elijah Griffin who
  23.     would not think of charging for them. Others are welcome to make
  24.     further modifications, such as bug fixes.
  25.     Sorry so few comments, but I only added what I needed myself.
  26.     (Actually most of the comments were added with a early version of
  27.     this extension. :^)
  28. */
  29.         
  30. /*
  31.     This external shows the use of some less trivial functionality.
  32.  
  33.     It puts up a dialog, and uses the text entered in the text field
  34.     to prefix every line, optionally in the selection.
  35. */
  36.  
  37. enum
  38. {
  39.     sel_only = 3,
  40.     
  41.     insert,
  42.     delete,
  43.     
  44.     beginning,
  45.     end,
  46.     
  47.     prefix_str,
  48.     suffix_str
  49. };
  50.  
  51. static struct
  52. {
  53.     Boolean    insert;
  54.     Boolean    line_start;
  55.     Boolean    line_end;
  56.     Boolean    sel_only;
  57.     Boolean    pad;
  58.     
  59.     Str255    prefix_str;
  60.     Str255    suffix_str;
  61. } prefix_info;
  62.  
  63. static void maintain_buttons(DialogPtr d)
  64. {
  65.     SetDlgCtl(d, insert, prefix_info.insert);
  66.     SetDlgCtl(d, delete, ! prefix_info.insert);
  67.     
  68. /*    SetDlgCtl(d, beginning, prefix_info.line_start);*/
  69. /*    SetDlgCtl(d, end, prefix_info.line_end);*/
  70.  
  71.     SetDlgCtl(d, sel_only, prefix_info.sel_only);
  72. }
  73.  
  74. pascal void main(ExternalCallbackBlock *callbacks, WindowPtr w)
  75. {
  76.     DialogPtr d;
  77.     GrafPtr save_port;
  78.     
  79.     long sel_end, sel_start, first_char;
  80.     long start_line, end_line;
  81.     long old_start;
  82.     
  83.     short item;
  84.     
  85.     Handle text;
  86.     char *s, *ss;
  87.     
  88.     RememberA0();
  89.     SetUpA4();
  90.     
  91.     GetPort(&save_port);
  92.     
  93.     d = callbacks->CenterDialog(128);
  94.     SetPort(d);
  95.     
  96.     callbacks->GetSelection(&sel_start, &sel_end, &first_char);
  97.     
  98.     prefix_info.insert = TRUE;
  99.     prefix_info.line_start = TRUE;
  100.     BlockMove("\p/* ", prefix_info.prefix_str, 4);
  101.     BlockMove("\p */", prefix_info.suffix_str, 4);
  102.     
  103.     prefix_info.sel_only = sel_end != sel_start;
  104.     
  105.     XAbleDlgCtl(d, sel_only, prefix_info.sel_only);
  106.         
  107.     SetStrItem(d, prefix_str, prefix_info.prefix_str);
  108.     SetStrItem(d, suffix_str, prefix_info.suffix_str);
  109.     
  110.     SelIText(d, prefix_str, 0, 255);
  111. /*    SelIText(d, suffix_str, 0, 255); */
  112.     
  113.     do {
  114.         maintain_buttons(d);
  115.         
  116.         ModalDialog(callbacks->StandardFilter, &item);
  117.         
  118.         switch (item)
  119.         {
  120.             case insert:
  121.             case delete:
  122.                 prefix_info.insert = (item == insert);
  123.                 break;
  124.                 
  125. /*            case beginning:*/
  126. /*                prefix_info.line_start = (item == beginning);*/
  127. /*                break;*/
  128. /**/
  129. /*            case end:*/
  130. /*                prefix_info.line_end = (item == end);*/
  131. /*                break;*/
  132.                 
  133.             case sel_only:
  134.                 prefix_info.sel_only = ! prefix_info.sel_only;
  135.                 break;
  136.         }
  137.     } while ((item != 1) && (item != 2));
  138.     
  139.     ReadStrItem(d, prefix_str, prefix_info.prefix_str);
  140.     ReadStrItem(d, suffix_str, prefix_info.suffix_str);
  141.         
  142.     DisposDialog(d);
  143.     SetPort(save_port);
  144.     
  145.     s = (char *)&prefix_info.prefix_str[0];
  146.     ss = (char *)&prefix_info.suffix_str[0];
  147.     
  148.     if ((item == 1) * ((s[0] != 0)+(ss[0] != 0))) {
  149.         start_line = 0;
  150.         end_line = callbacks->GetLastLine();
  151.         
  152.         if (prefix_info.sel_only) {
  153.             start_line = callbacks->GetLineNumber(sel_start);
  154.             end_line = callbacks->GetLineNumber(sel_end);
  155.         };
  156.             
  157.         callbacks->StartProgress("\pChanging Lines...", 2 * (end_line - start_line), FALSE);
  158.         old_start = start_line;
  159.         
  160.         if (s[0] != 0)
  161.         {
  162.             text = callbacks->GetWindowContents(w);
  163.             
  164. /*            if (prefix_info.line_start)    */
  165. /*            {*/
  166.                 if (prefix_info.insert)
  167.                 {
  168.                     for ( ; start_line < end_line; start_line++) {
  169.                         callbacks->DoProgress((2 * start_line) - old_start);
  170.                         
  171.                         sel_start = callbacks->GetLinePos(start_line);
  172.                         callbacks->SetSelection(sel_start, sel_start, first_char);
  173.                         callbacks->Insert((char *)&s[1], s[0]); 
  174.                     };
  175.                 }
  176.                 else /* !prefix_info.insert */
  177.                 {
  178.                     for ( ; start_line < end_line; start_line++) {
  179.                         callbacks->DoProgress((2 * start_line) - old_start);
  180.                         
  181.                         sel_start = callbacks->GetLinePos(start_line);
  182.                         
  183.                         if (callbacks->FindPattern(*text, sel_start + s[0] + 1, sel_start,
  184.                                                     &s[1], s[0], FALSE) >= 0)
  185.                         {
  186.                             callbacks->SetSelection(sel_start, sel_start + s[0], first_char);
  187.                             callbacks->Delete();
  188.                         }
  189.                     };
  190. /*                }*/
  191.             }
  192.         } /* if s!=0 */
  193.         
  194.         if (ss[0] != 0)
  195.         {
  196.             text = callbacks->GetWindowContents(w);
  197.             
  198.             start_line = old_start;
  199.             
  200. /*            if (prefix_info.line_end)    */
  201. /*            {*/
  202.                 if (prefix_info.insert)
  203.                 {
  204.                     for ( ; start_line < end_line; start_line++) {
  205.                         callbacks->DoProgress(start_line - old_start);
  206.                         
  207.                         sel_start = callbacks->GetLinePos(start_line);
  208.                         sel_start = callbacks->GetLineEnd(sel_start);
  209.                         
  210.                         callbacks->SetSelection(sel_start, sel_start, first_char);
  211.                         callbacks->Insert((char *)&ss[1], ss[0]); 
  212.                     };
  213.                 }
  214.                 else
  215.                 {
  216.                     for ( ; start_line < end_line; start_line++) {
  217.                         callbacks->DoProgress(start_line - old_start);
  218.                         
  219.                         sel_start = callbacks->GetLinePos(start_line);
  220.                         sel_end = callbacks->GetLineEnd(sel_start);
  221.                         
  222.                         if (callbacks->FindPattern(*text, sel_end, sel_end - ss[0],
  223.                                                     &ss[1], ss[0], FALSE))
  224.                         {
  225.                             callbacks->SetSelection(sel_end - ss[0], sel_end, first_char);
  226.                             callbacks->Delete();
  227.                         }
  228.                     };
  229. /*                }*/
  230.             }
  231.             
  232.             callbacks->DoneProgress();
  233.         }
  234.     };
  235.     
  236.     RestoreA4();
  237. }
  238.